package org.wu.framework.lazy.orm.database.jpa.repository.proxy;

import org.wu.framework.lazy.orm.database.jpa.repository.LazyJpaRepository;
import org.wu.framework.lazy.orm.database.jpa.repository.NoLazyRepositoryBean;
import org.wu.framework.lazy.orm.database.jpa.repository.core.LazyJapRepositoryMetadata;
import org.wu.framework.lazy.orm.database.jpa.repository.core.LazyJpaEntityMetadata;
import org.wu.framework.lazy.orm.database.jpa.repository.query.LazyQueryMetadata;
import org.wu.framework.lazy.orm.database.jpa.repository.query.LazyQueryMetadataFactory;
import org.wu.framework.lazy.orm.database.jpa.repository.support.LazySimpleQueryFactory;
import org.wu.framework.lazy.orm.database.jpa.repository.support.LazySimpleQuerySupport;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.proxy.AbstractLazyOperationProxyRetryInvocationHandler;

import java.lang.reflect.Method;

/**
 * LazyJpaRepository 代理对象
 */
public class LazyJpaRepositoryProxy extends AbstractLazyOperationProxyRetryInvocationHandler {

    private final LazyJapRepositoryMetadata lazyJapRepositoryMetadata;

    public LazyJpaRepositoryProxy(LazyJapRepositoryMetadata lazyJapRepositoryMetadata) {
        this.lazyJapRepositoryMetadata = lazyJapRepositoryMetadata;
    }

    /**
     * 开始重试执行
     *
     * @param proxy     代理对象
     * @param method    代理方法
     * @param args      代理方法参数
     * @param retryTime 重试次数
     * @param throwable 异常
     * @param hasRetry  是否已经重试
     */
    @Override
    public Object doRetryInvoke(Object proxy, Method method, Object[] args, int retryTime, Throwable throwable, boolean hasRetry) throws Throwable {

        LazyJpaEntityMetadata<?, ?, ?> lazyJpaEntityMetadata = lazyJapRepositoryMetadata.getLazyJpaEntityMetadata();
        Class<?> entityClass = lazyJpaEntityMetadata.getEntityClass();
        Class<?> repositoryClass = lazyJpaEntityMetadata.getRepositoryClass();

        LazyJpaRepository<?, ?> lazyJpaRepository = lazyJapRepositoryMetadata.getLazyJpaRepository();

        LazyLambdaStream lazyLambdaStream = lazyJapRepositoryMetadata.getLazyLambdaStream();


        // 执行方法信息

        Class<?> declaringClass = method.getDeclaringClass(); // 当前方法所在的类
        if (declaringClass.getAnnotation(NoLazyRepositoryBean.class) != null) {
            // 内置方法处理
            return method.invoke(lazyJpaRepository, args);
        } else if (LazyQueryMetadataFactory.support(method)) {

            LazyQueryMetadata lazyQueryMetadata = LazyQueryMetadataFactory.createLazyQueryMetadata(method, args, lazyLambdaStream);
            // 判断是否含有指定注解 @Select
            // 调用 LazyLambdaStream 进行数据处理
            LazySimpleQuerySupport lazySimpleQuerySupport = LazySimpleQueryFactory.createLazySimpleQuerySupport(lazyQueryMetadata);
            return lazySimpleQuerySupport.query();
        } else if (LazyQueryMetadataFactory.hasXml(method)) {
            // xml其他形式支持
        } else if (LazyQueryMetadataFactory.supportMethodName2SQL(method)) {

            LazyQueryMetadata lazyQueryMetadata = LazyQueryMetadataFactory.createLazyQueryMetadataByMethodName(method, args, lazyLambdaStream);
            // 通过方法名执行sql
            LazySimpleQuerySupport lazySimpleQuerySupport = LazySimpleQueryFactory.createLazySimpleQuerySupport(lazyQueryMetadata);
            return lazySimpleQuerySupport.query();
        }
        return method.invoke(this, args);

    }
}
